use crate::errors::MyError;
use crate::message::{MessageContext, MsgAction};
use crate::models::LoginInfo;
use crate::services::{get_code_source, get_img_code, login, register};
use crate::utils::{get_query_param, panic_if_err};
use gloo::console;
use stylist::yew::styled_component;
use wasm_bindgen_futures::spawn_local;
use web_sys::{window, HtmlInputElement};
use yew::{
    classes, function_component, html, use_context, use_effect_with, use_node_ref, use_state,
    Callback, Html,
};

#[styled_component]
pub fn LoginForm() -> Html {
    let _login_info = use_state(LoginInfo::default);
    let msg = use_context::<MessageContext>().expect("no ctx found");
    let code_source = use_state(String::new);

    let code_img = use_state(|| String::from(""));
    let user_name_ref = use_node_ref();
    let pwd_ref = use_node_ref();

    {
        //let code_img = code_img.clone();
        let code_source = code_source.clone();
        use_effect_with((), move |_| {
            spawn_local(async move {
                code_source.set(panic_if_err(get_code_source().await));
                //let img_code = panic_if_err(get_img_code(&code_source).await);
                //code_img.set(format!("data:image/png;base64,{}", img_code.img));
            });
        });
    };

    let reset_fields = {
        let user_name_ref = user_name_ref.clone();
        let pwd_ref = pwd_ref.clone();
        move || {
            user_name_ref
                .cast::<HtmlInputElement>()
                .unwrap()
                .set_value("");
            pwd_ref.cast::<HtmlInputElement>().unwrap().set_value("");
        }
    };

    let login_click = {
        let user_name_ref = user_name_ref.clone();
        let pwd_ref = pwd_ref.clone();
        let msg = msg.clone();
        let code_source = code_source.clone();
        Callback::from(move |_| {
            if let Some(client_id) = get_query_param("client_id") {
                let user_name: String = panic_if_err(
                    user_name_ref
                        .cast::<HtmlInputElement>()
                        .ok_or_else(|| MyError::ElementCastError("user_name_ref".to_string())),
                )
                .value();
                let pwd: String = panic_if_err(
                    pwd_ref
                        .cast::<HtmlInputElement>()
                        .ok_or_else(|| MyError::ElementCastError("pwd_ref".to_string())),
                )
                .value();
                let info = LoginInfo {
                    user_name,
                    pwd,
                    client_id,
                    code_source: code_source.to_string(),
                };
                let msg = msg.clone();
                spawn_local(async move {
                    match login(info).await {
                        Ok(res) => {
                            let _ = window()
                                .expect("window加载失败")
                                .location()
                                .replace(&format!(
                                    "{}?access_code={}",
                                    &res.redirect_path, &res.access_code
                                ));
                        }
                        Err(err) => {
                            msg.dispatch(MsgAction::ShowMsg(err.to_string()));
                        }
                    }
                });
            } else {
                msg.dispatch(MsgAction::ShowMsg("clientId不存在".to_string()));
            }
        })
    };

    let register_click = {
        let user_name_ref = user_name_ref.clone();
        let pwd_ref = pwd_ref.clone();
        let reset_fields = reset_fields.clone();
        Callback::from(move |_| {
            if let Some(client_id) = get_query_param("client_id") {
                let user_name: String = panic_if_err(
                    user_name_ref
                        .cast::<HtmlInputElement>()
                        .ok_or_else(|| MyError::ElementCastError("user_name_ref".to_string())),
                )
                .value();
                let pwd: String = panic_if_err(
                    pwd_ref
                        .cast::<HtmlInputElement>()
                        .ok_or_else(|| MyError::ElementCastError("pwd_ref".to_string())),
                )
                .value();
                let info = LoginInfo {
                    user_name,
                    pwd,
                    client_id,
                    code_source: code_source.to_string(),
                };
                let msg = msg.clone();
                let user_name_ref = user_name_ref.clone();
                let pwd_ref = pwd_ref.clone();
                let reset_fields = reset_fields.clone();
                spawn_local(async move {
                    match register(info).await {
                        Ok(_) => {
                            /*如果成功，直接返回一个redirect，因此不用在这里处理成功的情况*/
                            msg.dispatch(MsgAction::ShowMsg("注册成功，请登录".to_string()));

                            reset_fields();
                        }
                        Err(err) => {
                            msg.dispatch(MsgAction::ShowMsg(err.to_string()));
                        }
                    }
                });
            } else {
                msg.dispatch(MsgAction::ShowMsg("clientId不存在".to_string()));
            }
        })
    };

    html! {
    <div class={classes!("column", "content-center", "align-center","position-relative", "h-100vh",
        css!(r#"
            @media screen and (max-width: 475px) {
                width: 80%;
            }
            @media screen and (min-width: 476px) and (max-width: 800px) {
                width: 50%;
            }
            @media screen and (min-width: 801px) {
                width: 40%;
            }
            .input-container{
                display: flex;
                flex-direction: column;
            }
            .input-container input {
                width: 100%;
                height: 46px;
                line-height: 46px;
                padding-left: 16px;
                border-radius: 6px;
            }

            .sep {
                height: 16px;
                width: 50px;
            }

            .button-container {
                margin-top: 20px;
            }
            .button-container button {
                width: 100%;
                border:none;
                border-radius: 5px;
                height: 48px;
            }
        "#)
        )}>
        <div class={classes!("row", "content-center", css!(r#"
            padding: 0 0 24px 0;
            color: #141414;
            font-size: 24px;
            line-height: 32px;
            text-align: center;
           "#))}
        >
            {"账号登录"}
        </div>
        <div class={classes!("w-100")}>
            <div class="input-container">
                <div>
                    <input placeholder="用户名" ref={user_name_ref}/>
                </div>
                <div class="sep"/>
                <div>
                    <input type="password" placeholder="密码" ref={pwd_ref}/>
                </div>
            </div>
        </div>
        <div class={classes!("w-100")}>
            <div>
                {
                    if code_img.len() > 0 {
                        html! {
                            <img src={code_img.to_string()} alt="验证码图片"/>
                        }
                    } else  {
                        html! {}
                    }
                }
            </div>
            <div class={classes!("column", "content-end", "button-container")}>
                <button style="color:white;background-color:#21a675" onclick={login_click} >{"登录"}</button>
                <div class="sep"/>
                <button style="color:white;background-color:#c32136" onclick={register_click} >{"注册"}</button>
            </div>
      </div>
    </div>
    }
}
